﻿using FileTransfer.Assistantor;
using FileTransfer.Vollk.Except;
using FileTransfer.Vollk.Model;
using HAF.LogUtility.Except;
using System;
using System.IO;
using System.Text;

namespace FileTransfer.Vollk
{
    /// <summary>
    /// FTP参数解析器
    /// </summary>
    public class FtpParser
    {
        public static FtpSiteParameters ParseStr(string ftpUrl)
        {
            if (string.IsNullOrEmpty(ftpUrl) || ftpUrl.IndexOf("ftp://", StringComparison.CurrentCultureIgnoreCase) == -1)
            {
                throw new RunException((int)TransferCode.AddressErr, "ftp参数不对");
            }
            //字串中有多个@，要进行处理
            string tmpAlpha = FileAssistantor.EncodeBase64(Encoding.UTF8, "@");

            int i1 = ftpUrl.IndexOf('@');
            int i2 = ftpUrl.LastIndexOf('@');
            if (i2 > i1) 
            {
                string head = ftpUrl.Substring(0, i1+1);
                string tail = ftpUrl.Substring(i1 + 1, ftpUrl.Length - i1 -1);

                ftpUrl = string.Concat(head.Replace("@", tmpAlpha), tail);
            }

            var config = new FtpSiteParameters(ftpUrl);
            int startIndex = 0;
            var ftps = ftpUrl.Substring(6).Replace('\\', '/');
            if (ftps.IndexOf(":") > -1)
            {
                config.UserId = ftps.Substring(0, ftps.IndexOf(":"));
                int pIndex = ftps.Split('/')[0].LastIndexOf("@");
                if (pIndex > -1)
                {
                    config.Password = ftps.Substring(ftps.IndexOf(":") + 1, pIndex - ftps.IndexOf(":") - 1);
                }
                config.UserId = config.UserId.Replace(tmpAlpha, "@");
                config.Password = config.Password.Replace(tmpAlpha, "@");

                startIndex = pIndex + 1;
            }
            int endIndex = ftps.IndexOf('/', startIndex);
            if (endIndex == -1)
                endIndex = ftps.Length;

            config.SiteRootUrl = string.Concat("ftp://", ftps.Substring(0, endIndex));
            var adds = ftps.Substring(startIndex, endIndex - startIndex).Split(':');
            config.IP = adds[0];
            config.Site = IpToLong(config.IP).ToString();
            if (adds.Length > 1)
            {
                config.Port = int.Parse(adds[1]);
            }
            
            if (ftps.IndexOf("/") > -1)
            {
                config.FileSets = new System.Collections.Generic.List<FileStruct>();

                string tmpfile = ftps.Substring(ftps.IndexOf("/") + 1);
                if (tmpfile.StartsWith("/"))
                {
                    tmpfile = tmpfile.Remove(0,1);
                }
                config.RemotePath = Path.GetDirectoryName(tmpfile).Replace("\\", "/");
                string dateStr = DateTime.Now.ToString("yyyyMM");
                //下载到本地的文件地址处理
                string tmpFileName = Path.GetFileName(tmpfile);
                string tmpExtName = Path.GetExtension(tmpfile);
                string rFile = tmpFileName;
                //string rFile = allowGuid ? string.Concat(Guid.NewGuid().ToString("N"), tmpExtName) : tmpFileName;
                //注意：Path.Combine使用时，后续的地址不能加/或者//
                string localFileSavePath = Path.Combine(LoadContext.DefaultSaveAddress, dateStr, rFile);

                config.FileSets.Add(new FileStruct()
                {
                    ID = Guid.NewGuid().ToString("N"),
                    Name = tmpFileName,
                    FileExtName = tmpExtName,
                    LocalPath = localFileSavePath,
                    RemotePath = tmpfile,
                    Size = 0,
                    Site = config.Site,
                    BEnable = true
                });
            }
            

            return config;
        }

        /// <summary>
        /// IP地址数值化
        /// </summary>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        public static long IpToLong(String ipAddress)
        {
            //将目标IP地址字符串strIPAddress转换为数字
            string[] arrayIP = ipAddress.Split('.');
            long sip1 = Int64.Parse(arrayIP[0]);
            long sip2 = Int64.Parse(arrayIP[1]);
            long sip3 = Int64.Parse(arrayIP[2]);
            long sip4 = Int64.Parse(arrayIP[3]);

            long r1 = sip1 * 256 * 256 * 256;
            long r2 = sip2 * 256 * 256;
            long r3 = sip3 * 256;
            long r4 = sip4;

            long result = r1 + r2 + r3 + r4;
            return result;

            //IPAddress ip = IPAddress.Parse("1.0.0.2");
            //byte[] bb = ip.GetAddressBytes();
            //Array.Reverse(bb);
            //uint xxx = System.BitConverter.ToUInt32(bb, 0);
        }

        /// <summary>
        /// 将int型表示的IP还原成正常IPv4格式
        /// </summary>
        /// <param name="intIPAddress">int型表示的IP</param>
        /// <returns></returns>
        public static string NumberToIP(long intIPAddress)
        {
            long tempIPAddress;
            //将目标整形数字intIPAddress转换为IP地址字符串
            //-1062731518 192.168.1.2 
            //-1062731517 192.168.1.3 
            if (intIPAddress >= 0)
            {
                tempIPAddress = intIPAddress;
            }
            else
            {
                tempIPAddress = intIPAddress + 1;
            }
            long s1 = tempIPAddress / 256 / 256 / 256;
            long s21 = s1 * 256 * 256 * 256;
            long s2 = (tempIPAddress - s21) / 256 / 256;
            long s31 = s2 * 256 * 256 + s21;
            long s3 = (tempIPAddress - s31) / 256;
            long s4 = tempIPAddress - s3 * 256 - s31;
            if (intIPAddress < 0)
            {
                s1 = 255 + s1;
                s2 = 255 + s2;
                s3 = 255 + s3;
                s4 = 255 + s4;
            }
            string strIPAddress = s1.ToString() + "." + s2.ToString() + "." + s3.ToString() + "." + s4.ToString();
            return strIPAddress;
        }

        /// <summary>
        /// 将int型表示的IP还原成正常IPv4格式
        /// </summary>
        /// <param name="intIPAddress">数值型的IP</param>
        /// <returns>计算好的IP地址</returns>
        public static string NumberToIP2(long n_ip)
        {   //临时用于装载需要计算的ip字符串的数值
            long tmp_ip = n_ip;
            //返回计算好的ip地址字符串
            string str_ip = string.Empty;

            for (int i = 3; i >= 0; i--)
            {  //整除得到当前节点ip字符串
                str_ip += tmp_ip / Convert.ToInt64(Math.Pow(256, i));
                //判断是否为最后不用加.
                str_ip += (i > 0 ? "." : "");
                //取余得到下级需要计算的ip字符串的数值
                tmp_ip = n_ip % Convert.ToInt64(Math.Pow(256, i));
            }

            return str_ip;
        }
    }
}
